The goal of this project was to design a smart home user interface that can easily control the lights and door lock in a smart equipped home. Using speech to text and facial recognition, Pi-Home Voice can securely control your home devices from anywhere.

For this project, we designed a touch and vocal user interface on the Raspberry Pi 4 and PiTFT with a USB Microphone that sends commands to control smart connected home devices. We had three devices we could control, including the living room light, kitchen light, and the door lock. The goal of this project was to be able to speak commands, control, and monitor the home devices wirelessly using PyGame and PiGame for the touch user interface and SpeechRecognition for the voice recognition. We made a model home with 2 LEDs for the kitchen and living room lights and a servo motor for a raising and lowering door latch. These devices were wired to a Raspberry Pi Zero W server in the model home. The Raspberry Pi 4 user interface was used to send commands to the R-Pi Zero W server over WIFI and configure the devices after a vocal command was given using the Python Socket library. The Raspberry Pi 4 is secured through facial ID and uses a Raspberry Pi Camera and OpenCV to distinguish the owner of the device. We developed our own ML Random Forest Classifier to map voice commands to actionable commands for the R-PI Zero W to implement in the model home.

Vocal Recognition

The overall design of the system was to have the user say a command to control devices in our model home. For the commands we trained an ML Random Forest Classifier to interpret variations of requesting the following commands:

  1. Turn on kitchen light
  2. Turn off kitchen light
  3. Turn on living room light
  4. Turn off living room light
  5. Open door
  6. Close door

The ML classifier trained on 120+ text outputs from the SpeechRecognition Python module which uses Google Speech API model to convert speech to text. The speech inputs to the model to create this training data specified 20 permutations per command of the action and location maping to each of the 6 commands. The ML classifier also trained on invalid commands which mapped to a 7th type of action, that is, telling the devices to do nothing. The following table shows valid and invalid commands:

Valid Command Invalid Command Reason
"Turn on the light in the kitchen, please" "Turn on the light" No location specified
"Living room light off" "Living Room" No action specified
"Open the door" "Open the living room" Wrong action for specified location

As seen with the first valid command, the model accepts lots of extra words and can still recognize the correct command if both location and action are specified.

Testing Vocal Recognition

To test the vocal recogition we spoke a variety of short and long phrases with the expectation of our model detecting a certain command or deeming it invalid. For long phrases such as "Can you please open the door right now" and short phrases such as "Door open" the model successfully classified these to the correct commands. Most of the testing was testing the accuracy of our ML text-to-command model since the Google Speech API speech-to-text has been verified by numerous English users of the framework. For the vocal recording with the USB Microphone, we found a suitable length of 3 seconds to capture a command from the user. Of course, we wrapped up our testing with invalid phrases such as "hello" and "turn on the light" which correctly mapped to no command being issued. Thus, our vocal recognition models proved to be very robust.

PyGame Touch User Inteface

We used Pygame for the graphical user interface shown in figure 1. We used pygame rects that change color to show the status of our 3 smart connected devices, where green means on and open, while red means off and closed for the light and door, respectively. The GUI also shows whether the R-Pi 4 is connected to the internet with the string 'WIFI' the color green meaning connected and red meaning disconnected. The string 'CLIENT' indicates whether the R-Pi 4 server is connected to the RPi-Zero W client over WIFI with green meaning connected and red meaning disconnected. The GUI also includes a video feed so that when the approved user aligns the connected Pi Camera to their face, the 'tap to log in/out' button may be pressed and our OpenCV facial recognition model will determine if the user be allowed to log in. If the user is logged in the 'logged in' pygame circle rect will be green, otherwise it will be red and nothing can be pressed except the log in/out button. The voice record button may be pressed to initiate a vocal recording through a connected USB microphone that will be interpreted by our speech to command models and can be cancelled at anypoint in the recording by pressing the stop button.

Testing GUI

To test the GUI, we wanted to ensure that everything displayed correctly on the PiTFT after we developed on the HDMI display. For this we saw that everything was visable and a ledgible font size. Next, we tested our touch display making sure we could press buttons on the display. If the user was logged out, we made sure only the log in/out button could be pressed, while if the user was logged in, the microphone and log in/out buttons were pressable. We also checked the frame rate of our camera display and made sure it was smooth, changing the sleep value until it was satisfactory.

Facial Recognition

Figure 4

Figure 4. Facial recognition logged-in

Figure 5

Figure 5. Facial recognition logged-out

Facial recognition is done with the help of OpenCV and the Pi Camera. To create an allowed user profile, we snap 20 photos of the subject and use these photos to train the facial recognizer model. This model is saved and loaded when facial recognition is done during a log in request. We ran into issues with getting the Pi Camera and HDMI display to work concurrently on the Pre-empt RT patched Bullseye OS. By downgrading to the Lab 3 Bullseye OS we were able to get the camera and HDMI monitor to display simulatanously as normal. We also ran into issues with the accuracy of our facial recognition. The facial recognition profile was set to a user with black hair and sometimes other users with black hair would also be recognized. The facial recognition would remain accurate against others with different hair colors tested. The lighting impacted the performance of the facial recognition. When the photos for the user profile were taken in dark light, the model would see more similarities to non-users with similar hair color, while photos taken in higher contrast lighting allowed the model to distingish better between hair color.

Smart Connected Devices

The smart connected devices include 2 LEDs (one in the kitchen and the other in the living room) and a servo motor that controls the raising and lowering of a door latch. Devices are controled with the R-Pi Zero W through GPIO configurations to turn on or off the LEDs and control the motor to spin. These controls are triggered from requests sent from the host R-Pi 4 over WIFI through Socket Python. We used TCP to establish connection and send commands from the R-Pi 4 to R-Pi Zero. We used a static IP address of the lab room to create the server on the R-Pi 4 that the client R-Pi Zero could connect to. We ran into issues at first trying to establish a dynamic address that didn't depend on luck of the IP address not changing. We tried using the MAC address of the R-Pi 4 and the ARP linux command to identify the R-Pi 4 server to connect to from the R-Pi Zero. We ran into issues with the Cornell firewall not allowing device discovery via this method so we resorted to static IP. After various lab sessions, we noticed that the IP of our R-Pi connection to internet did not change so we were able to keep this address static and successfully connect from R-Pi Zero to 4 with out any special tricks.

Testing Smart Connected Devices

To test the smart connected devices, we tested to make sure the device statuses on the PiTFT screen matched what is seen in the actual model home shown in figure 2. The model home LEDs were easy to test on or off, while the servo motor had to be tuned to ensure that the door latch would open or close all the way. We powered the servo motor off 6V battery power, while the R-Pi Zero W ran off the power supply. There were many times the battery wires would unplug themselves as we moved the model home around. This would cause the motor to not move when we sent a command and this issue was easily fixed by soldering the wire to a breadboard wire with a stronger connection. There were some issues with the port being in use after consecutive runs of the server setup on the R-Pi 4. While this was an issue in development where we ran consecutive requests to establish a server on a given port, for the actual demo, the port would free up by the time we rebooted the R-Pi Zero (within a few minutes) and would not cause a connection issue. We realized that since the R-Pi Zero does not have a touch display, we would add a quit button. For this we used a button wired to a GPIO that would trigger on a falling edge for a callback to quit the program. This allowed us a fail safe for testing the R-Pi zero without a monitor.

Overall, the system performed as expected. We were able to report that we met our set timeline tasks each week so much that we added additional functionality to our initial plan with facial recognition security. The only goal we did not meet was implementing a temperature sensor on the R-Pi to read and set the temperature. We achieved a framework that could be applied to voice control numerous other smart connected home devices. This includes HVAC, electric window shades, smart dimmers, color changing light bulbs, etc. The speech-to-command was the most robust part of our system, while the facial recognition left room for improvement. For WIFI, the connection ended up working, however, may require changing the IP Address periodically as it changes on busy networks (such as Cornell WIFI). For home connections, the IP may not change and this will not be an issue.

Our project showed that many smart connected home devices could be easily be integrated into our voice-to-command framework. For future work, we look to explore adding more commands to our model for controlling HVAC, electric window shades, smart dimmers, color changing light bulbs, and thermostat devices. We also hope to explore more consistent connection types such as Bluetooth if the devices expect to be in close range, or creating a WIFI server that never changes address for the client to always be able to find. We would also like to improve the security of our device by improving the accuracy of our facial recognition and adding other layers of protection to our device (maybe a numerical passcode). Finally, we may add multiple users to the device and set up profiles for each and what devices they may be able to control. This means an updated GUI which has settings that may be configured and profiles that may be learned for a given user of our device. With this we can look to implement scheduled commands and automations (turn the lights off every day after 11 PM).

Item Cost
Raspberry Pi 4 $0
Lab 3 Robot Kit $0
Raspberry Pi Zero W $10
Raspberry Pi Camera $15
Cardboard $0
LEDs $0
USB Microphone $6
Total $31

main.py

                
                    
                    import time
                    from time import sleep
                    import pygame, pigame
                    from pygame.locals import *
                    from threading import Thread
                    import sys
                    from pathlib import Path
                    import RPi.GPIO as GPIO
                    import subprocess 
                    import speech_recognition as sr
                    from speech_recognition.recognizers import google, whisper
                    from joblib import load
                    import numpy as np
                    import socket
                    import time
                    import os 
                    import io
                    import picamera
                    import face_recognition
                    
                    #uncomment to display on the PiTFT
                    #os.putenv('SDL_VIDEODRV','fbcon')
                    #os.putenv('SDL_FBDEV','/dev/fb0')
                    #os.putenv('SDL_MOUSEDRV','dummy')
                    #os.putenv('SDL_MOUSEDEV','/dev/null')
                    #os.putenv('DISPLAY','')
                    
                    #thread to configure the facial ID
                    def task_3():
                    	global user_img
                    	global result_list
                    	global secure_login	
                    	global camera
                    	result_list = []
                    	camera.capture('/home/pi/new/project/unknown.jpg') #take a picture using Pi Camera
                    	unknown_image = face_recognition.load_image_file('/home/pi/new/project/unknown.jpg')
                    	try:
                    		unknown_encoding = face_recognition.face_encodings(unknown_image)[0]
                    		for encodings in user_img:
                    			if len(encodings) > 0:
                    				result = face_recognition.compare_faces([encodings], unknown_encoding)
                    				result_list.append(result)
                    			else:
                    				result_list.append([False])
                    				
                    		flattened_list = [item for sublist in result_list for item in sublist]
                    		count_true = sum(flattened_list)
                    		count_false = len(flattened_list) - count_true
                    		print('true: ', count_true)
                    		print('false: ', count_false)
                    		if count_true >= 8: #compare camera capture with usr_img profile. If greater than 8, log in
                    			secure_login = 1
                    	except:
                    		pass
                    		
                    	while(1):
                    		break
                    
                    
                    
                    
                    #WIFI server thread
                    def task_2():	
                    	global wifi
                    	global connection 
                    	run = 1
                    	while(run): #Test if PI-4 is connected to a WIFI network before proceeding
                    		try:
                    			#socket.setdefaulttimeout(3)
                    			s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    			s.connect(("8.8.8.8",53))
                    			s.close()
                    			run = 0
                    			wifi = 1 #Pi-4 is connected to a wifi network
                    		except:	
                    			run = 1
                    	def start_server(): #now start the server
                    		global new_predictions
                    		global connection
                    		IP = subprocess.run(['hostname', '-I'], check=True, stdout=subprocess.PIPE, text=True)
                    		#convert input to str
                    		host = str(IP.stdout.strip()) #start connection using IP of current WIFI network connection
                    		port = 6000    # Port number
                    
                    
                    		# Create a socket object
                    		with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
                    			# Bind to the host and port
                    			server_socket.bind((host, port))
                    
                    			# Start listening for connectios
                    			server_socket.listen(1)
                    			#print(f"Server is listening on {host}:{port}")
                    
                    			# Accept a connection
                    			client_socket, addr = server_socket.accept()
                    			with client_socket:
                    				print('Connected by', addr)
                    				connection = 1
                    				while True:
                    					# Prepare data to send
                    					client_socket.sendall(new_predictions.encode()) #send command every second
                    					time.sleep(1)
                    
                    	if __name__ == '__main__':
                    		start_server()
                    
                    
                    
                    
                    #audio recording thread
                    def task_1():
                    	global new_predictions
                    	global recording 
                    	global run_thread 
                    	global text_arr
                    	recording = 1
                    	run_thread = 1
                    	#start recording para: card number, device number, duration
                    	result = subprocess.run(['sudo', 'arecord', '-D', 'plughw:1,0', '-d', '3', '/home/pi/new/project/new.wav'])
                    	#convert input to str
                    	recognizer = sr.Recognizer()
                    	try:
                    		with sr.AudioFile('/home/pi/new/project/new.wav') as source:
                    			audio_data = recognizer.record(source)
                    			text = recognizer.recognize_google(audio_data) #use google API for speech-to-text
                    			text_arr = np.append(text_arr, text)
                    			new_inputs = [text]
                    			new_predictions = model.predict(new_inputs) #convert the speech-to-text output to a command 1,2,...,7
                    			new_predictions = new_predictions[0]
                    			print(new_predictions)
                    	except:
                    		pass
                    
                    	#break the thread after running
                    	run_thread = 0
                    	recording = 0
                    	while(1):
                    		break
                    #quit button callback
                    def GPIO17_callback(channel):
                    	global run
                    	run = 0
                    	quit()
                    
                    	
                    
                    	
                    
                    # GPIOS Config
                    GPIO.setmode(GPIO.BCM)
                    GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)
                    GPIO.add_event_detect(17, GPIO.FALLING, callback = GPIO17_callback, bouncetime = 300)
                    #load our ML Random Forest model for text to command conversion
                    model = load('/home/pi/new/project/speech.joblib')
                    
                    
                    size = width, height = 320, 240
                    pygame.init()
                    lcd = pygame.display.set_mode((320,240))
                    lcd.fill((0,0,0))
                    pygame.display.update()
                    mic_icon = pygame.image.load('/home/pi/new/project/mic_icon.png')
                    pitft = pigame.PiTft()
                    # flag for code run
                    run = 1
                    recording_done = 0
                    new_predictions = ''
                    recording = 0
                    run_thread = 0
                    sid_id =''
                    send = False
                    text_arr = np.array([''])
                    wifi = 0
                    connection = 0
                    #start server thread
                    t2 = Thread(target=task_2)
                    t2.start()
                    # arr entries -> kitchen, living room, doorlock
                    indication_arr = np.array([0,0,0])
                    
                    font = pygame.font.SysFont('Arial', 15)
                    text_l = font.render('L Light', True, (255, 255, 255))
                    text_l_rect = text_l.get_rect()
                    text_l_rect.center = (40, 170)
                    
                    text_k = font.render('K Light', True, (255, 255, 255))
                    text_k_rect = text_k.get_rect()
                    text_k_rect.center = (100, 170)
                    
                    text_d = font.render('Door', True, (255, 255, 255))
                    text_d_rect = text_d.get_rect()
                    text_d_rect.center = (160, 170)
                    
                    text_lo = font.render('logged out', True, (255, 255, 255))
                    text_lo_rect = text_d.get_rect()
                    text_lo_rect.center = (237, 105)
                    
                    text_li = font.render('logged in', True, (255, 255, 255))
                    text_li_rect = text_d.get_rect()
                    text_li_rect.center = (237, 105)
                    
                    font = pygame.font.SysFont('Arial', 12)
                    text_login = font.render('Tap to log in/out -->', True, (255, 255, 255))
                    text_login_rect = text_d.get_rect()
                    text_login_rect.center = (200, 225)
                    
                    text_wifi_off = font.render('WIFI', True, (255, 0, 0))
                    text_wifi_off_rect = text_d.get_rect()
                    text_wifi_off_rect.center = (180, 30)
                    
                    text_wifi_on = font.render('WIFI', True, (0, 255, 0))
                    text_wifi_on_rect = text_d.get_rect()
                    text_wifi_on_rect.center = (180, 30)
                    
                    text_client_off = font.render('CLIENT', True, (255, 0, 0))
                    text_client_off_rect = text_d.get_rect()
                    text_client_off_rect.center = (167, 45)
                    
                    text_client_on = font.render('CLIENT', True, (0, 255, 0))
                    text_client_on_rect = text_d.get_rect()
                    text_client_on_rect.center = (167, 45)
                    
                    
                    #start Pi camera
                    camera = picamera.PiCamera()
                    camera.resolution = (128, 96)
                    rgb = bytearray(camera.resolution[0] * camera.resolution[1] *3)
                    
                    #for face recognition load the user profile
                    image_path = ['/home/pi/new/project/data/image_' + str(i) + '.jpg' for i in range(10)]
                    user_img = []
                    result_list = []
                    for path in image_path:
                    	image = face_recognition.load_image_file(path)
                    	encoding = face_recognition.face_encodings(image)[0]
                    	user_img.append(encoding)
                    ##################
                    secure_login = 0
                    
                    
                    while(run):
                    	if new_predictions == '1':
                    		indication_arr[0] = 1
                    	if new_predictions == '2':
                    		indication_arr[0] = 0
                    	if new_predictions == '3':
                    		indication_arr[1] = 1
                    	if new_predictions == '4': 
                    		indication_arr[1] = 0
                    	if new_predictions == '5':
                    		indication_arr[2] = 1
                    	if new_predictions == '6':
                    		indication_arr[2] = 0
                    	lcd.fill((0,0,0))
                    	#record button
                    	lcd.blit(pygame.transform.scale(mic_icon, (50, 50)), (20,10))
                    	#kitchen light
                    	pygame.draw.circle(lcd, (250,0,0), (40, 200), 10)
                    	#living room light
                    	pygame.draw.circle(lcd, (250,0,0), (100, 200), 10)
                    	#door lock
                    	pygame.draw.circle(lcd, (250,0,0), (160, 200), 10)
                    	#### facial recognition
                    	if secure_login == 0:
                    		pygame.draw.rect(lcd, (0,0,255), pygame.Rect(290,210,30,30))
                    	else:
                    		pygame.draw.rect(lcd, (0,255,0), pygame.Rect(290,210,30,30))
                    	
                    	#for i in range(text_arr.shape[0]):
                    	lcd.blit(text_l, text_l_rect)
                    	lcd.blit(text_k, text_k_rect)
                    	lcd.blit(text_d, text_d_rect)
                    	lcd.blit(text_login, text_login_rect)
                    	stream = io.BytesIO()
                    	camera.capture(stream, use_video_port=True, format = 'rgb')
                    	stream.seek(0)
                    	stream.readinto(rgb)
                    	stream.close()
                    	cam_img = pygame.image.frombuffer(rgb[0:(camera.resolution[0] * camera.resolution[1] * 3)], camera.resolution, 'RGB')
                    	lcd.blit(cam_img, (200,0))	
                    	for event in pygame.event.get():
                    		if(event.type == pygame.MOUSEBUTTONDOWN):
                    			x,y = pygame.mouse.get_pos()
                    		elif(event.type == pygame.MOUSEBUTTONUP):
                    			x,y = pygame.mouse.get_pos()
                    			#if click record button
                    			if 70 >= x >= 20 and 60 >= y >= 10 and run_thread == 0 and secure_login == 1:
                    				t1 = Thread(target=task_1)
                    				t1.start()
                    			if 320 >= x >= 290 and 240 >= y >= 210:
                    				if secure_login == 0:
                    					t3 = Thread(target=task_3)
                    					t3.start()
                    				else:
                    					secure_login = 0
                    				
                    	for i in range(len(indication_arr)):
                    		if (indication_arr[i]):
                    			pygame.draw.circle(lcd, (0,255,0), (40 + i*60, 200), 10)
                    			
                    	if recording == 1:
                    		pygame.draw.rect(lcd, (255,0,0), pygame.Rect(0,0,70,70))
                    	if secure_login == 0:
                    		lcd.blit(text_lo, text_lo_rect)
                    		pygame.draw.circle(lcd, (250,0,0), (257,129), 10)
                    	if secure_login == 1:
                    		lcd.blit(text_li, text_li_rect)
                    		pygame.draw.circle(lcd, (0,255,0), (257,129), 10)
                    	if wifi == 0:
                    		lcd.blit(text_wifi_off, text_wifi_off_rect)
                    	else:
                    		lcd.blit(text_wifi_on, text_wifi_on_rect)
                    	if connection == 0:
                    		lcd.blit(text_client_off, text_client_off_rect)
                    	else:
                    		lcd.blit(text_client_on, text_client_on_rect)
                    		
                    	pygame.display.update()
                    	pitft.update()
                    	sleep(0.01)
                    		
                    GPIO.cleanup()
                    quit()
                    
                

client.py

                
                    
                    import socket
                    import RPi.GPIO as GPIO
                    from time import sleep
                    
                    #setup GPIOs
                    GPIO.setmode(GPIO.BCM)
                    GPIO.setup(14, GPIO.OUT)
                    GPIO.setup(17,GPIO.OUT)
                    GPIO.output(17, GPIO.HIGH)
                    GPIO.output(17, GPIO.LOW)
                    GPIO.setup(12,GPIO.OUT)
                    GPIO.setup(20,GPIO.OUT)
                    GPIO.setup(21,GPIO.OUT)
                    pwm_0 = GPIO.PWM(12, 50) #50 frequency 
                    GPIO.output(20, GPIO.LOW)
                    GPIO.output(21, GPIO.LOW)
                    pwm_0.start(20)
                    temp = '99999'
                    
                    
                    def GPIO6_callback(channel):		
                    	GPIO.cleanup()
                    	quit()
                    GPIO.setup(6, GPIO.IN, pull_up_down=GPIO.PUD_UP)
                    GPIO.add_event_detect(6, GPIO.FALLING, callback = GPIO6_callback, bouncetime = 300)
                    def connect_to_server():
                    	run = 1
                    	while(run):
                    		try:
                    			s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    			s.connect(("8.8.8.8",53))
                    			s.close()
                    			run = 0
                    		except:
                    			run = 1
                    	global temp
                    	
                    	host = '10.49.67.157'
                    	port = 6000
                    	
                    	#Create a socket object
                    	with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client_socket:
                    		print("Connect to the server")
                    		client_socket.connect((host, port))
                    		print(f"Connected to {host}:{port}")
                    		
                    		while True:
                    			#Receive the response
                    			data = client_socket.recv(1024)
                    			if not data:
                    				sleep(1)
                    			print('Received:', data.decode())
                    			if data.decode() == '1' and temp != data.decode(): #turn on living room light
                    				temp = data.decode()
                    				GPIO.output(14, GPIO.HIGH)
                    			if data.decode() == '2' and temp != data.decode(): #turn off living room light
                    				temp = data.decode()
                    				GPIO.output(14, GPIO.LOW)
                    			if data.decode() == '3' and temp != data.decode(): #turn on kitchen light
                    				temp = data.decode()
                    				GPIO.output(17, GPIO.HIGH)
                    			if data.decode() == '4' and temp != data.decode(): #turn off kitchen light
                    				temp = data.decode()
                    				GPIO.output(17, GPIO.LOW)
                    			if data.decode() == '5' and temp != data.decode(): #open the door
                    				temp = data.decode()
                    				GPIO.output(20, GPIO.LOW)
                    				GPIO.output(21, GPIO.HIGH)
                    				sleep(1.3)
                    			if data.decode() == '6' and temp != data.decode(): #close the door
                    				temp = data.decode()
                    				GPIO.output(20, GPIO.HIGH)
                    				GPIO.output(21, GPIO.LOW)
                    				sleep(1.3)
                    			GPIO.output(20, GPIO.LOW)
                    			GPIO.output(21, GPIO.LOW)
                    			sleep(1)
                    				
                    if __name__ == '__main__':
                    	connect_to_server()
                    
                

test_ml.py

                
                    
                    import numpy as np
                    from sklearn.model_selection import train_test_split
                    from sklearn.feature_extraction.text import TfidfVectorizer
                    from sklearn.svm import SVC
                    from sklearn.pipeline import make_pipeline
                    from sklearn.metrics import classification_report
                    from joblib import dump
                    from sklearn.ensemble import RandomForestClassifier
                    
                    import pandas as pd
                    data = pd.read_csv("Book1.csv", usecols=['X_train '])
                    data = np.array([data])
                    X_train = np.array([''])
                    for i in range(130):
                        X_train = np.append(X_train, data[0][i][0])
                    X = np.delete(X_train, 0)
                    
                    data = pd.read_csv("Book1.csv", usecols=['Y_train '])
                    data = np.array([data])
                    Y_train = np.array([''])
                    for i in range(130):
                        Y_train = np.append(Y_train, data[0][i][0])
                    y = np.delete(Y_train, 0)
                    
                    
                    
                    
                    
                    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)
                    
                    model = make_pipeline(TfidfVectorizer(), RandomForestClassifier())
                    
                    
                    model.fit(X_train, y_train)
                    dump(model, 'speech.joblib')
                    
                    predictions = model.predict(np.array(['oino oi']))
                    predictions

                    
                

Book1.csv

                
                    
                X_train	Y_train
turn on light in living room	1
trun off light in living room	2
turn on light in kitchen	3
trun off light in kitchen	4
open door	5
close door	6
turn on door	5
turn off door	6
open light	7
close light	7
living room kitchen	7
living room bathroom on	7
living room bathroom off	7
open living room	7
open bathroom	7
light on in living room	1
turn light on in living room	1
living room turn on  light	1
turn on living room light	1
could you please turn on light in living room	1
get some light in living room	1
get some light in living room	1
turn off living room light	2
could you turn off living room light	2
switch off living room light	2
kill living room light	2
turn off light in living room	2
could you please open door	5
open door	5
let us open door	5
pop door open	5
open front door	5
close door	6
let us close door	6
shut door	6
check weather	7
get a coffee	7
when is coffee shop open	7
turn on volumn	7
turn off volumn	7
tell me a joke	7
what to do tonight	7
have some fun	7
is it rain	7
iddo oidno doqm Doiqmo	7
living room light on	1
turn on living room	1
turn living room light on	1
light up living room	1
make living room brighter	1
add more light to living room	1
brighten living room	1
make it brighter in living room	1
lights on in living room	1
make living room light	1
lower light in living room	2
lower living room light	2
turn off living room	2
turn light off in living room	2
dark in living room	2
stop here living room lights off	2
turn living room light off	2
turn lights down in living room	2
lower lighting in living room	2
dim living room	2
lower light level in living room	2
darken living room	2
lights out in living room	2
kitchen light on	3
turn on kitchen	3
turn kitchen light on	3
light up kitchen	3
make kitchen brighter	3
add more light to kitchen	3
brighten kitchen	3
make it brighter in kitchen	3
lights on in kitchen	3
make kitchen light	3
lower light in kitchen	4
lower kitchen light	4
turn off kitchen	4
turn light off in kitchen	4
dark in kitchen	4
stop here kitchen lights off	4
turn kitchen light off	4
turn lights down in kitchen	4
lower lighting in kitchen	4
dim kitchen	4
lower light level in kitchen	4
darken kitchen	4
lights out in kitchen	4
on light kitchen	3
kitchen on light	3
kitchen on light	3
kitchen off light	4
kitchen light off	4
light kitchen off	4
open door	5
make door open	5
crack door open	5
release door	5
swing door open	5
open door wide	5
slide open door	5
door open	5
Open Door	5
close door	6
door closed	6
close door	6
shut door	6
make door shut	6
close door	6
door shut	6
shut down	6
lock door	6
lock door	6
living kitchen	7
shut living room	7
open living room	7
close light	7
hello	7
how are you	7
hi	7
stop	7
try again	7
is this on	7
recording	7
light door	7
turn off light	7
turn on light	7
close light	7
open light	7
shut light	7
light on	7
light off	7
     
                

Figure 6

Jacob Revelo

Jacob worked on making the website report, built, wired and calibrated the model home, generated the ML Random Forest training data, and got the R-Pi Zero W OS working. He worked with Chuqiao to establish WIFI connection between R-Pi 4 and Zero and troubleshooting major issues.

Figure 7

Chuqiao Yao

Chuqiao configured the Pi Camera and used OpenCV to get the facial recognition working on the Pygame. He got the USB microphone speech-to-text working. He worked with Jacob to make the Pygame display on the Pitft for tapping to record voice commands, showing status of devices and connections, and logging into the system.